package top.yehot.kettle.boot.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.pentaho.di.repository.AbstractRepository;
import org.pentaho.di.repository.LongObjectId;
import org.pentaho.di.repository.RepositoryDirectory;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.RepositoryElementMetaInterface;
import org.pentaho.di.repository.filerep.KettleFileRepository;
import org.pentaho.di.repository.kdr.KettleDatabaseRepository;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import lombok.extern.slf4j.Slf4j;
import top.yehot.cmm.util.core.base.BaseException;
import top.yehot.cmm.util.core.base.Result;
import top.yehot.kettle.boot.core.utils.FileUtil;
import top.yehot.kettle.boot.core.utils.RepositoryUtil;
import top.yehot.kettle.boot.enums.KettleResEnum;
import top.yehot.kettle.boot.models.vo.directory.DirectoryAddVO;
import top.yehot.kettle.boot.models.vo.directory.DirectoryEditVO;
import top.yehot.kettle.boot.models.vo.directory.DirectoryVO;
import top.yehot.kettle.boot.service.DirectoryService;

/**
 * 资源库树 服务实现类
 * 
 * @author lquan
 * @date 2022年5月28日 下午6:52:35
 */
@Slf4j
@Service
public class DirectoryServiceImpl implements DirectoryService {

	@Override
	public List<DirectoryVO> findTree(String repoId, String pid) {
		// 根节点
		DirectoryVO root = null;
		// 获取资源库对象
		AbstractRepository abstractRepository = RepositoryUtil.getRepository(repoId);
		try {
			// 父节点为空或NULL，默认获取根节点
			if (!StringUtils.hasText(pid)) {
				root = rootDir(abstractRepository);
				pid = root.getId();
			}
			
			RepositoryDirectoryInterface rdi;
			// 获取当前节点信息
			if (abstractRepository instanceof KettleDatabaseRepository) {
				rdi = abstractRepository.loadRepositoryDirectoryTree().findDirectory(new LongObjectId(Long.valueOf(pid)));
			} else {
				rdi = abstractRepository.loadRepositoryDirectoryTree().findDirectory(pid);
			}
			
			// 临时存放树数据
			List<DirectoryVO> tmpDirs = new ArrayList<>();
			// 统计当前节点下有多少子节点
			int subDirSize = rdi.getNrSubdirectories();
			if (subDirSize > 0) {
				// 循环封装对象，并且放入集合中
				for (int i = 0; i < subDirSize; i++) {
					RepositoryDirectory subDir = rdi.getSubdirectory(i);
					tmpDirs.add(new DirectoryVO()
						.setId(subDir.getObjectId().getId())
			        	.setPid(subDir.getParent().getObjectId().getId())
			        	.setText(subDir.getName())
			        	.setFullPath(subDir.getPath())
			        );
				}
			}
			
			// 不是根节点不处理
			if (null == root) return tmpDirs;
			
			root.setChildren(tmpDirs);
			return Arrays.asList(root);
		} catch (Exception e) {
			log.error(KettleResEnum.DIR_ERR.getMsg(), e);
			throw new BaseException(KettleResEnum.DIR_ERR);
		}
	}
	
	@Override
	public Result<?> createDir(DirectoryAddVO param) {
		AbstractRepository abstractRepository = RepositoryUtil.getRepository(param.getRepId());
		try {
			RepositoryDirectoryInterface directory;
			if (abstractRepository instanceof KettleFileRepository) {
				directory = abstractRepository.loadRepositoryDirectoryTree().findDirectory(param.getDirPId());
			} else {
				directory = abstractRepository.loadRepositoryDirectoryTree().findDirectory(new LongObjectId(Long.valueOf(param.getDirPId())));
			}
			RepositoryDirectoryInterface directoryChild = directory.findChild(param.getDirName());
			if (null == directoryChild) {
				abstractRepository.createRepositoryDirectory(directory, param.getDirName());
			} else {
				return Result.of(KettleResEnum.DIR_NAME_EXIST);
			}
			return Result.success();
		} catch (Exception e) {
			log.error(KettleResEnum.DIR_CREATE_ERR.getMsg(), e);
			throw new BaseException(KettleResEnum.DIR_CREATE_ERR);
		}
	}
	
	@Override
	public Result<?> modifyDir(DirectoryEditVO param) {
		AbstractRepository abstractRepository = RepositoryUtil.getRepository(param.getRepId());
		// 获取新文件名
		String newDirName = param.getDirName();
		try {
			RepositoryDirectoryInterface directory;
			if (abstractRepository instanceof KettleFileRepository) {
				// TODO 这个有问题
//				directory = abstractRepository.loadRepositoryDirectoryTree().findDirectory(param.getDirId());
//				abstractRepository.renameRepositoryDirectory(directory.getObjectId(), directory.getParent(), param.getDirName());
				
				KettleFileRepository fileRepo = (KettleFileRepository) abstractRepository;
				// 获取资源库根路径
				String basePath = FileUtil.removeEndSlash(fileRepo.getRepositoryMeta().getBaseDirectory());
				
				// 构建旧的文件对象
				File oldFile = new File(basePath + param.getDirId());
				// 构建新的文件对象
				File newFile = new File(oldFile.getParent() + FileUtil.separator + newDirName);
				
				// 文件名称相同不做操作
				if (oldFile.getName().equals(newDirName)) return Result.success();
				// 存在不修改
				if (newFile.exists()) return Result.of(KettleResEnum.DIR_NAME_EXIST);
				
				// 重命名
				oldFile.renameTo(newFile); 
			} else {
				directory = abstractRepository.loadRepositoryDirectoryTree().findDirectory(new LongObjectId(Long.valueOf(param.getDirId())));
				abstractRepository.renameRepositoryDirectory(new LongObjectId(Long.valueOf(param.getDirId())), directory.getParent(), param.getDirName());
			}
			return Result.success();
		} catch (Exception e) {
			log.error(KettleResEnum.DIR_MODIFY_ERR.getMsg(), e);
			throw new BaseException(KettleResEnum.DIR_MODIFY_ERR);
		}
	}
	
	@Override
	public Result<?> deleteDir(String repId, String dirId) {
		AbstractRepository abstractRepository = RepositoryUtil.getRepository(repId);
		boolean exist = false;
		try {
			RepositoryDirectoryInterface directory;
			if (abstractRepository instanceof KettleFileRepository) {
				KettleFileRepository fileRepo = (KettleFileRepository) abstractRepository;
				// 获取资源库根路径
				String basePath = FileUtil.removeEndSlash(fileRepo.getRepositoryMeta().getBaseDirectory());
				// 判断文件夹下是否还有文件
				File[] childFiles = new File(basePath + dirId).listFiles();
				if (null != childFiles && childFiles.length > 0) exist = true;
				
				directory = abstractRepository.loadRepositoryDirectoryTree().findDirectory(dirId);
			} else {
				directory = abstractRepository.loadRepositoryDirectoryTree().findDirectory(new LongObjectId(Long.valueOf(dirId)));
				// 获取当前目录下所有脚本
				List<RepositoryElementMetaInterface> jobTranList = abstractRepository.getJobAndTransformationObjects(directory.getObjectId(), false);
				// 判断当前目录下是否有子目录或脚本
				if (!CollectionUtils.isEmpty(directory.getChildren()) || !CollectionUtils.isEmpty(jobTranList)) exist = true;
			}
			if (exist) {
				return Result.of(KettleResEnum.DIR_CHIRED_EXIST);
			}
			
			abstractRepository.deleteRepositoryDirectory(directory);
			return Result.success();
		} catch (Exception e) {
			log.error(KettleResEnum.DIR_DELETE_ERR.getMsg(), e);
			throw new BaseException(KettleResEnum.DIR_DELETE_ERR);
		}
	}
	
	/** 获取根节点信息 **/
	private DirectoryVO rootDir(AbstractRepository abstractRepository) throws Exception {
		try {
			RepositoryDirectoryInterface rdi = abstractRepository.loadRepositoryDirectoryTree().findDirectory("/");
	        return new DirectoryVO()
	        		.setId(rdi.getObjectId().getId())
	        		.setText("/")
	        		.setFullPath("/");
		} catch (Exception e) {
			throw e;
		}
	}

}
